/************************************************************************/
/*Copyright (c) James Zhao 2007,2008
/*This file is part of AdminOverlay.
/*AdminOverlay is free software: you can redistribute it and/or modify
/*it under the terms of the GNU General Public License as published by
/*the Free Software Foundation, either version 3 of the License, or
/*(at your option) any later version.
/*
/*AdminOverlay is distributed in the hope that it will be useful,
/*but WITHOUT ANY WARRANTY; without even the implied warranty of
/*MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
/*GNU General Public License for more details.
/*
/*You should have received a copy of the GNU General Public License
/*along with AdminOverlay.  If not, see <http://www.gnu.org/licenses/>.                                                                     */
/*************************************************************************/
#include "GraphicsAdapter.h"
#include "InputManager.h"
#include "GameOverlay.h"
#include "RendererModules/directx9GUIRenderer/d3d9renderer.h"
#include "CEGUI.h"
using namespace CEGUI;

GameOverlay *GameOverlay::currentInstance = NULL;
void GameOverlay::InitalizeImmediateServices(HINSTANCE instance, DWORD threadID)
{
 	inputManager = new InputManager(this);
 	inputManager->initalize(instance, threadID);
}

void GameOverlay::InitalizeDelayedServices()
{
	graphicsAdapter = new GraphicsAdapter();
	graphicsAdapter->SetDrawHandler(&GameOverlay::DrawHandler);
	graphicsAdapter->SetPreResetHandler(&GameOverlay::PreResetHandler);
	graphicsAdapter->SetPostResetHandler(&GameOverlay::PostResetHandler);
	graphicsAdapter->setupDetours();
	IsActive(true);
	inputManager->setupDetours();
}

InputManager * GameOverlay::GetInputManager() const
{
	return inputManager;
}

GraphicsAdapter * GameOverlay::GetGraphicsAdapter() const
{
	return graphicsAdapter;
}

bool GameOverlay::IsActive() const
{
	return isActive;
}

void GameOverlay::IsActive( bool val )
{
	if(val != isActive)
	{
		isActive = val;
		graphicsAdapter->DisableForward(!isActive);
	}
}
//removes the file name
//c:/win32/sys.exe -> c:/win32/
void RemoveFileName(char *filePath)
{
	int lastSlash = -1;
	int i = 0;
	while(*(filePath+i) != NULL)
	{
		if(*(filePath+i) == '/' || *(filePath+i) == '\\')
		{
			lastSlash = i;
		}
		i++;
	}
	if(lastSlash == -1)
		return;
	*(filePath + lastSlash + 1) = NULL;
}
#define MODULENAME TEXT("Overlay.dll")
void GameOverlay::DrawHandler( LPDIRECT3DDEVICE9 device )
{
	GameOverlay* curInstance = GameOverlay::currentInstance;
	if(curInstance->requireResizeOp)
	{
		LoadLibrary(TEXT("CEGUIExpatParser_d.dll"));
		LoadLibrary(TEXT("CEGUIFalagardWRBase_d.dll"));
		int width = curInstance->graphicsAdapter->CachedWidth();
		int height = curInstance->graphicsAdapter->CachedHeight();

		curInstance->uiRenderer->setDisplaySize
			(CEGUI::Size(width, height));
		curInstance->rootWindow->setMaxSize(CEGUI::UVector2( 
			CEGUI::UDim(0, width), CEGUI::UDim(0, height)));
		curInstance->rootWindow->setSize(CEGUI::UVector2( 
			CEGUI::UDim(0, width), CEGUI::UDim(0, height)));
	}
	if(curInstance->uiRenderer == NULL)
	{
		int width = curInstance->graphicsAdapter->CachedWidth();
		int height = curInstance->graphicsAdapter->CachedHeight();
		curInstance->uiRenderer = new CEGUI::DirectX9Renderer(device, 0);
		new CEGUI::System(curInstance->uiRenderer);

		// 		
		CEGUI::DefaultResourceProvider* rp = static_cast<CEGUI::DefaultResourceProvider*>
			(CEGUI::System::getSingleton().getResourceProvider());
		
		//fix for memory errors
		char dirBuff1[255];
		GetModuleFileNameA(GetModuleHandle(MODULENAME), dirBuff1, 255);
		RemoveFileName(dirBuff1);
		char dirBuff2[255];
		GetModuleFileNameA(GetModuleHandle(MODULENAME), dirBuff2, 255);
		RemoveFileName(dirBuff2);
		char dirBuff3[255];
		GetModuleFileNameA(GetModuleHandle(MODULENAME), dirBuff3, 255);
		RemoveFileName(dirBuff3);
		char dirBuff4[255];
		GetModuleFileNameA(GetModuleHandle(MODULENAME), dirBuff4, 255);
		RemoveFileName(dirBuff4);
		char dirBuff5[255];
		GetModuleFileNameA(GetModuleHandle(MODULENAME), dirBuff5, 255);
		RemoveFileName(dirBuff5);
		char dirBuff6[255];
		GetModuleFileNameA(GetModuleHandle(MODULENAME), dirBuff6, 255);
		RemoveFileName(dirBuff6);

		char* schemesDir = strcat(dirBuff1, "datafiles/schemes/");
		char* imagesetsDir = strcat(dirBuff2, "datafiles/imagesets/");
		char* fontsDir = strcat(dirBuff3, "datafiles/fonts/");
		char* layoutsDir = strcat(dirBuff4, "datafiles/layouts/");
		char* looknfeelsDir = strcat(dirBuff5, "datafiles/looknfeel/");
		char* luaScriptsDir = strcat(dirBuff6, "datafiles/lua_scripts/");
		
		
		rp->setResourceGroupDirectory("schemes", schemesDir);
		rp->setResourceGroupDirectory("imagesets", imagesetsDir);
		rp->setResourceGroupDirectory("fonts", fontsDir);
		rp->setResourceGroupDirectory("layouts", layoutsDir);
		rp->setResourceGroupDirectory("looknfeels", looknfeelsDir);
		rp->setResourceGroupDirectory("lua_scripts", luaScriptsDir);

		CEGUI::Imageset::setDefaultResourceGroup("imagesets");
		CEGUI::Font::setDefaultResourceGroup("fonts");
		CEGUI::Scheme::setDefaultResourceGroup("schemes");
		CEGUI::WidgetLookManager::setDefaultResourceGroup("looknfeels");
		CEGUI::WindowManager::setDefaultResourceGroup("layouts");
		CEGUI::ScriptModule::setDefaultResourceGroup("lua_scripts");


		// load in the scheme file, which auto-loads the TaharezLook imageset
		CEGUI::SchemeManager::getSingleton().loadScheme( "VanillaSkin.scheme");
		CEGUI::SchemeManager::getSingleton().loadScheme( "WindowsLook.scheme");
		CEGUI::SchemeManager::getSingleton().loadScheme( "TaharezLook.scheme");

		System::getSingleton().setDefaultMouseCursor( "TaharezLook", "MouseArrow" );

		// load in a font.  The first font loaded automatically becomes the default font.
		if(! CEGUI::FontManager::getSingleton().isFontPresent( "Agency-FB-Bold" ) )
			CEGUI::FontManager::getSingleton().createFont( "agencyb.font" );
		curInstance->rootWindow = WindowManager::getSingleton().loadWindowLayout( "test.layout" );
		System::getSingleton().setGUISheet( curInstance->rootWindow );

// 		CEGUI::WindowManager& wmgr = CEGUI::WindowManager::getSingleton();
// 		curInstance->rootWindow = wmgr.createWindow( "DefaultWindow", "root" );
// 		curInstance->rootWindow->setMaxSize(CEGUI::UVector2( 
// 			CEGUI::UDim(0, width), CEGUI::UDim(0, height)));
// 		curInstance->rootWindow->setSize(CEGUI::UVector2( 
// 			CEGUI::UDim(0, width), CEGUI::UDim(0, height)));
// 		CEGUI::System::getSingleton().setGUISheet(curInstance->rootWindow );
// 		FrameWindow* fWnd = 
// 			(FrameWindow*)wmgr.createWindow("Vanilla/FrameWindow","testWindow");
// 		curInstance->rootWindow->addChildWindow( fWnd );
// 		// position a quarter of the way in from the top-left of parent.
// 		fWnd->setPosition( UVector2( UDim( 0, 100 ), UDim( 0, 100 ) ) );
// 
// 		// set size to be half the size of the parent
// 		
// 		fWnd->setSize( UVector2( UDim( 0, 400 ), UDim( 0, 200 ) ) );
// 		fWnd->setText( "HELLO WORLD 12345" );
		curInstance->inputManager->Start();		
	}
	CEGUI::System::getSingleton().renderGUI();
}
void GameOverlay::PreResetHandler()
{
	GameOverlay::currentInstance->uiRenderer->preD3DReset();
}
void GameOverlay::PostResetHandler()
{

	GameOverlay::currentInstance->uiRenderer->postD3DReset();
	GameOverlay::currentInstance->requireResizeOp = true;
	
}
GameOverlay::GameOverlay( void )
{
	GameOverlay::currentInstance = this;	
	requireResizeOp = false;
}